<template>
	<view class="uon-preview-box">
		
		<template v-if="$slots.default">
			<view @click="handler()">
				<slot></slot>
			</view>
		</template>
		<template v-else>
			<image class="image_" :mode="mode" :src="src" :style="imgStyle" @click="handler()"></image>
		</template>
		
		<view class="preview-bxo" v-if="previewShow">
			<view class="icon iconfont close_" @click="handlerClose()">X</view>
			<view class="bottom_">
				<view class="icon iconfont" @click="handlerScale(1)">+</view>
				<view class="icon iconfont" @click="recover()">  </view>
				<view class="icon iconfont" @click="handlerScale(2)">-</view>
				<!-- <view class="icon iconfont">&#xe66b;</view>
				<view class="icon iconfont">&#xe66a;</view> -->
			</view>
			
			<view v-if="list && list.length > 1" class="icon iconfont left_" @click="handlerChange(1)">&#xe63c;</view>
			<view v-if="list && list.length > 1" class="icon iconfont right_" @click="handlerChange(2)">&#xe618;</view>
			
			<movable-area class="movable_area">
				<template v-for="(item, i) in movableViewList" :key="i">
					<movable-view
					v-if="item.show"
					:x="mx" :y="my"
					direction="all" 
					class="movale_"
					disabled="true"
					:animation="animationMovable"
					:style="item.view" 
					scale out-of-bounds 
					:scale-value="scaleValue" 
					:scale-max="4"
					@change="onChange"
					@scale="scale">
						<image class="preview_image" 
						:src="item.src"
						:style="{width: item.view.width, height: item.view.height, opacity: item.imgShow ? 1 : 0}"
						 @load="load" @error="error"></image>
					</movable-view>
				</template>
				
				<view  v-if="showMovableLoading" class="loading"></view>
				
				<movable-view class="error-mov" v-if="showImageError" direction="none" disabled="true">
					<view class="img-error">
						<view class="loader"></view>
						<view class="btn_" @click="reloadImage()">点击重新加载</view>
					</view>
				</movable-view>
			</movable-area>
		</view>
		
	</view>
</template>
<script>
import { nextTick } from 'vue'
	export default {
		props: {
			mode: {
				type: String,
				default: 'widthFix'
			},
			src: {
				type: String,
				default: ''
			},
			width: {
				type: String,
				default: 'auto'
			},
			height: {
				type: String,
				default: 'auto'
			},
			preview: {
				type: Boolean,
				default: true
			},
			// 预览数组
			list: {
				type: [Array, undefined],
				default: undefined
			},
			// 预览照片下标
			imgIndex: {
				type: Number,
				default: -1
			},
			// 数组中预览照片的 key 值
			keyName: {
				type: String,
				default: ''
			}
		},
		watch: {
			src: {
				handler(newval) {
					// 动态修改照片时从新计算预览图
					if(newval) this.initImage({ src: newval })
				}
			},
			list: {
				handler(newval) {
					console.log('list---', newval)
				},
				deep: true
			}
		},
		computed: {
			imgStyle() {
				return {
					width: this.setImgWidth,
					height: this.setImgHeight
				}
			},
		},
		data() {
			return {
				mx: 0,
				my: 0,
				imageIndex: 0,
				setImgWidth: '',
				setImgHeight: '',
				windowWidth: '',
				windowHeight: '',
				animationMovable: false,
				previewShow: false,
				showMovableView: false,
				showMovableLoading: true,
				showImageError: false,
				scaleValue: 1,
				previewIndex: 0,
				movableViewList: [
					// { show: false, view: { width: '', height: '', top: '', left: '' }, imgShow: false, src: '' },
				]
			}
		},
		created() {
			const _this = this
			// 获取系统信息
			uni.getSystemInfo({
				success(res) {
					_this.windowHeight = res.windowHeight
					_this.windowWidth = res.windowWidth
					_this.initImage({ width: res.windowWidth, height: res.windowHeight })
				}
			})
		},
		methods: {
			// 初始化
			initImage(options) {
				const { src = '', width = '', height = '', type = 1 } = options
				const _this = this
				let windowWidth = width ? width : _this.windowWidth
				let windowHeight = height ? height : _this.windowHeight
				
				// 获取预览图信息
				uni.getImageInfo({
					src: src ? src : _this.src,
					success: function (image) {
						// 初始化照片展示宽高
						if(type == 1) {
							if(_this.width == 'auto') _this.setImgWidth = image.width * 2 + 'rpx'
							else _this.setImgWidth = _this.width
							
							if(_this.height != 'auto') _this.setImgHeight = _this.height
						}
					}
				});
			},
			// 获取预览图样式
			getItemMovable(src, i) {
				const _this = this
				// 获取预览图信息
				uni.getImageInfo({
					src: src,
					success: function (image) {
						// 记录计算后的预览照片宽高
						let setWidth = 0, setHeight = 0, left = '0%', top = '0%'
						
						// 预览图初始 宽高 计算
						if(image.width < _this.windowWidth) {
							setWidth = image.width
							setHeight = image.height
						}else {
							setWidth = _this.windowWidth
							setHeight = ((_this.windowWidth * image.height) / image.width).toFixed(0)
						}
						
						// 预览图高小于可视高时垂直居中
						if(setHeight < _this.windowHeight) {
							// 计算垂直剧中
							const offset = (_this.windowHeight - Number(setHeight)) / 2
							top = ((offset / _this.windowHeight) * 100).toFixed(0) + '%'
						}else top = '0%'
						
						// 根据预览图宽度水平居中
						if(setWidth < _this.windowWidth) {
							// 计算水平居中
							const offset = (_this.windowWidth - setWidth) / 2
							left = ((offset / _this.windowWidth) * 100).toFixed(0) + '%'
						}else left = '0%'
						
						_this.movableViewList[i] = { 
							show: true, view: { width: setWidth + 'px', height: setHeight + 'px', top: top, left: left }, 
							imgShow: false, src: image.path
						}
					},
					fail(err) {
						console.log(222, err)
						_this.showMovableLoading = false
						_this.showImageError = true
					}
				});
			},
			handlerClose() {
				this.showImageError = false
				this.showMovableLoading = true
				this.previewShow = false
			},
			// 点击预览
			handler() {
				if(!this.preview) return
				
				if(this.list) {
					this.movableViewList = Array(this.list.length)
					.fill({ show: false, view: { width: '', height: '', top: '', left: '' }, showImg: false, src: '' });
					this.getItemMovable(this.src, this.imgIndex)
				}else {
					this.movableViewList = Array(1)
					.fill({ show: false, view: { width: '', height: '', top: '', left: '' }, showImg: false, src: '' });
					this.getItemMovable(this.src, 0)
				}
				
				this.scaleValue = 1
				this.mx = 0
				this.my = 0
				
				if(this.list && this.list.length > 0 && this.imgIndex != -1) this.previewIndex = this.imgIndex
				
				this.previewShow = true
			},
			// 预览图缩放操作
			handlerScale(type) {
				if(this.showImageError || this.showMovableLoading) return
				
				let scaleNum = this.scaleValue
				// 放大
				if(type === 1) scaleNum += 0.1
				// 缩小
				if(type === 2) scaleNum -= 0.1
				
				if(scaleNum < 0.5 || scaleNum > 4) return
				
				this.scaleValue = Number(scaleNum.toFixed(1))
			},
			// // 记录移动操作点
			// onChange(e) {
			// 	this.mx = e.detail.x
			// 	this.my = e.detail.y
			// },
			// // 位置复原
			// recover() {
			// 	if(this.showImageError || this.showMovableLoading) return
				
			// 	this.scaleValue = 1
			// 	setTimeout(() => {
			// 		this.mx = 0
			// 		this.my = 0
			// 	}, 100)
			// },
			// 预览照片切换
			handlerChange(type) {
				this.scaleValue = 1
				this.mx = 0
				this.my = 0
				
				let index = this.previewIndex
				
				this.showImageError = false
				this.movableViewList[index].show = false
				this.movableViewList[index].imgShow = false
				this.showMovableLoading = true
				
				if(type === 1) {
					if(this.previewIndex <= 0) this.previewIndex = this.list.length - 1
					else this.previewIndex -= 1
					
				}else {
					if(this.previewIndex >= (this.list.length - 1)) this.previewIndex = 0
					else this.previewIndex += 1
				}
				
				// if(!this.movableViewList[this.previewIndex].src) this.showMovableLoading = true
				
				if(!this.movableViewList[this.previewIndex].src) this.getItemMovable(this.keyName ? this.list[this.previewIndex][this.keyName] : this.list[this.previewIndex], this.previewIndex)
				else {
					this.movableViewList[this.previewIndex].show = true
				}
			},
			scale(e) {
				this.scaleValue = e.detail.scale
			},
			// 照片加载成功
			load(e) {
				// console.log('成功--', e)
				setTimeout(() => {
					this.movableViewList[this.previewIndex].imgShow = true
					this.showMovableLoading = false
					this.showImageError = false
				}, 200)
			},
			// 照片加载失败
			error(e) {
				// console.log('失败--', e)
				this.movableViewList[this.previewIndex].show = false
				this.movableViewList[this.previewIndex].imgShow = false
				this.showMovableLoading = false
				this.showImageError = true
			},
			// 重新加载照片
			reloadImage() {
				this.showMovableLoading = true
				this.showImageError = false
				if(this.list) {
					this.getItemMovable(this.keyName ? this.list[this.previewIndex][this.keyName] : this.list[this.previewIndex], this.previewIndex)
				}else {
					this.getItemMovable(this.src, 0)
				}
			}
		}
	}
</script>
<style lang="scss" scoped>

.uon-preview-box {
	position: relative;
	display: inline-block;
	.image_ {
		display: block;
	}
	.preview-bxo {
		position: fixed;
		width: 100vw;
		height: 80vh;
		left: 0rpx;
		top: 0rpx;
		z-index: 998;
		background-color: rgba(0, 0, 0, 0.5);
		display: flex;
		justify-content: center;
		align-items: center;
		.close_ {
			position: absolute;
			right: 40rpx;
			top: 50rpx;
			width: 60rpx;
			height: 60rpx;
			display: flex;
			align-items: center;
			justify-content: center;
			background-color: rgba(96,98,102, 0.5);
			border-radius: 50%;
			color: #E5E5E5;
			z-index: 100;
			font-size: 46rpx;
		}
		.bottom_ {
			position: absolute;
			bottom: 60rpx;
			width: 400rpx;
			height: 80rpx;
			border-radius: 50rpx;
			display: flex;
			background-color: rgba(96,98,102, 0.5);
			justify-content: space-around;
			align-items: center;
			z-index: 100;
			&>view {
				font-size: 56rpx;
				color:#E5E5E5
			}
		}
		.left_, .right_ {
			position: absolute;
			top: 50%;
			margin-top: -35rpx;
			width: 70rpx;
			height: 70rpx;
			display: flex;
			align-items: center;
			justify-content: center;
			background-color: rgba(96,98,102, 0.5);
			border-radius: 50%;
			color: #E5E5E5;
			z-index: 100;
			font-size: 50rpx;
		}
		.left_ {
			left: 30rpx;
		}
		.right_ {
			right: 30rpx;
		}
		.movable_area {
			width: 100%;
			height: 100%;
			display: flex;
			align-items: center;
			justify-content: center;
			flex-direction: column;
			pointer-events: none;
		}
		.movale_ {
			pointer-events: auto;
			height: max-content;
			position: absolute !important;
			.preview_image {
				display: block;
				transition: .3s;
			}
		}
	}
	
	.loading {
	  position: relative;
	  width: 30px;
	  height: 30px;
	  border: 2px solid #409EFF;
	  border-top-color: rgba(255, 255, 255, 0.6);
	  border-right-color: rgba(255, 255, 255, 0.6);
	  border-bottom-color: rgba(255, 255, 255, 0.6);
	  border-radius: 100%;
	
	  animation: circle infinite 0.75s linear;
	}
	
	@keyframes circle {
	  0% {
	    transform: rotate(0);
	  }
	  100% {
	    transform: rotate(360deg);
	  }
	}
	.error-mov {
		pointer-events: auto;
		width: 250rpx;
		height: 200rpx;
		position: absolute;
		top: 50%;
		margin-top: -100rpx;
		left: 50%;
		margin-left: -125rpx;
	}
	.img-error {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: space-between;
		color: rgba(255, 255, 255, 0.5);
		width: 250rpx;
		height: 200rpx;
	}
	.btn_ {
		font-size: 30rpx;
		padding: 10rpx 20rpx;
		background-color: #999;
		border-radius: 30rpx;
		color: #e5e5e5;
	}
	.loader {
	  width: 64px;
	  height: 64px;
	  position: relative;
	  background: rgba(255, 255, 255, 0.7);
	  border-radius: 4px;
	  overflow: hidden;
	}
	
	.loader:before {
	  content: "";
	  position: absolute;
	  left: 0;
	  bottom: 0;
	  width: 40px;
	  height: 40px;
	  transform: rotate(45deg) translate(30%, 40%);
	  background: #f1f1f1;
	  box-shadow: 32px -34px 0 5px #999999;
	}
	
	.loader:after {
	  content: "";
	  position: absolute;
	  left: 10px;
	  top: 10px;
	  width: 16px;
	  height: 16px;
	  border-radius: 50%;
	  background: #999999;
	  transform: rotate(0deg);
	  transform-origin: 35px 145px;
	}
}
</style>
